<?php
namespace App\Model;

use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Eloquent\Builder;


class Model extends Eloquent{

    /**
     * @var array 访问器黑名单
     * 建议改为protected属性，如果改为public，就可以在实例化对象后直接修改属性，然后再查数据
     */
    public $disableAccessors = [];

	
	// 特别注意： Builder的扩展方法不是一定要在construct 方法中实现，靠谱一点的写法应该是在laravel的provider类中的boot方法里面写
	// 这里只是为了能在一个文件中展示出来, 偷懒的写法
	 public function __construct(array $attributes = []){

        parent::__construct($attributes);
		
		$this->init();
    }
	
   
    private function init(array $attributes = []){
        
        Builder::macro('disableAccessor', function($columns = ['*']){
            $columns = is_array($columns) ? $columns : func_get_args();
            $model = $this->getModel();
            $model->disableAccessors = $columns;
            return $this->setModel($model);
        });
		
    }


    /**
     * Create a new model instance that is existing.
     * 此处重写了Eloquent 中的方法，目的是为了使disableAccessors生效
     *
     * @param  array  $attributes
     * @param  string|null  $connection
     * @return static
     */
    public function newFromBuilder($attributes = [], $connection = null)
    {
        $model = $this->newInstance([], true);

        $model->setRawAttributes((array) $attributes, true);

        $model->setConnection($connection ?: $this->getConnectionName());

        $model->fireModelEvent('retrieved', false);

        $model->disableAccessors = $this->disableAccessors; // 增加这一行，因为在get 方法和first方法中，是根据原来模型重新构造新的模型的

        return $model;
    }

    /**
     * Create a new instance of the given model.
     * 此处重写了Eloquent 中的方法，目的是为了使disableAccessors生效
     *
     * @param  array  $attributes
     * @param  bool  $exists
     * @return static
     */
    public function newInstance($attributes = [], $exists = false)
    {
        // This method just provides a convenient way for us to generate fresh model
        // instances of this current model. It is particularly useful during the
        // hydration of new objects via the Eloquent query builder instances.
        $model = new static((array) $attributes);

        $model->exists = $exists;

        $model->setConnection(
            $this->getConnectionName()
        );
		
        $model->disableAccessors = $this->disableAccessors; // 和上一个方法同样道理

        return $model;
    }


  
    public function usableAccessor($columns){ // 这里只是举个例子，你们自己写自己的逻辑，偷懒的也可以用这个方法
        if(in_array('*', $this->disableAccessors)) return false;
        return !in_array($columns, $this->disableAccessors);
    }
    

}